package com.gwtapps.messenger.client.view;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.gwtapps.messenger.client.model.Contact;
import com.gwtapps.messenger.client.model.Message;

// the mapView looks like ContactListView
public class MapView extends Composite{
	
	public Map<String, Character> allCharacters = new HashMap<String, Character>();
	
	MessengerView view;
	
	int mainGameWindowSizeWidth=640;		//game window size W
	int mainGameWindowSizeHeight=480;		//game window size H
	
	private AbsolutePanel map=new AbsolutePanel();				// Permits abs. pos. of widgets
	private AbsolutePanel mapContaierPan=new AbsolutePanel();	// Permits abs. pos. of widgets
	private FocusPanel focPan=new FocusPanel();				// Permits mouse event capture
	
	private Image grid=new Image("./MSEF000.gif");
	
	private int mapPositionX=-520;				// Map position X
	private int mapPositionY=-370;				// Map position Y
	
	private int mouseOnMapPositionX=+520;		// Mouse position on map X
	private int mouseOnMapPositionY=+370;		// Mouse position on map Y
	
	/*Move Map's Booleans if one of them is true map will move to its direction*/
	private boolean mapMoveRight=false;
	private boolean mapMoveLeft=false;
	private boolean mapMoveUp=false;
	private boolean mapMoveDown=false;
	
	int lenghtOfTileOnXDirection=40;
	int lenghtOfTileOnYDirection=30;
	
	int startX=lenghtOfTileOnXDirection*48;				//start position of creation of tiles   X/ size * 48  EX: 48*20=960 ,20 tiles in x direction*/
	int startY=0;
	
//	Label gx;
//	Label gy;
//	Label x;
//	Label y;
//	Label mx;
//	Label my;
	
	
	@SuppressWarnings("deprecation")
	public MapView(final MessengerView view) {
		
//		gx=new Label("gx:");
//		gy=new Label("gy:");
//		x=new Label("x:");
//		y=new Label("y:");
//		mx=new Label("mx:");
//		my=new Label("my:");
//		RootPanel.get("btn22").add(gx);
//		RootPanel.get("btn22").add(gy);
//		RootPanel.get("btn22").add(x);
//		RootPanel.get("btn22").add(y);
//		RootPanel.get("btn22").add(mx);
//		RootPanel.get("btn22").add(my);

		this.view = view;
		mapContaierPan.setPixelSize(mainGameWindowSizeWidth, mainGameWindowSizeHeight);
		mapContaierPan.setStyleName("outerAbsolutePanel");
		
		
		
		for(int i=0;i<lenghtOfTileOnYDirection+1;i++){		/*    Y  \ 	*/
			for(int j=0;j<lenghtOfTileOnXDirection+1;j++){ 	/*    X /  	*/
				Image tile=new Image("./brda000.gif");
				map.add(tile);
				map.setWidgetPosition(tile, startX-(j*48),startY+(j*12)  );
			}
			startX+=32;
			startY+=24;
		}
		map.setPixelSize(startX+48, startY+(12*lenghtOfTileOnXDirection)+12);
		
		Image.prefetch("./gfx/items/bikes/bike0.gif");
		Image bike=new Image("./gfx/items/bikes/bike0.gif");
		map.add(bike);
		map.setWidgetPosition(bike, 816,440  );
		DOM.setStyleAttribute(bike.getElement(), "zIndex", ""+41);
		
		Image.prefetch("./gfx/items/bikes/bike1.gif");
		Image bike2=new Image("./gfx/items/bikes/bike1.gif");
		map.add(bike2);
		map.setWidgetPosition(bike2, 784,488  );
		DOM.setStyleAttribute(bike2.getElement(), "zIndex", ""+45);
		
		Image.prefetch("./gfx/items/bikes/bike2.gif");
		Image bike3=new Image("./gfx/items/bikes/bike2.gif");
		map.add(bike3);
		map.setWidgetPosition(bike3, 560,584  );
		DOM.setStyleAttribute(bike3.getElement(), "zIndex", ""+53);
		
		Image.prefetch("./gfx/items/bikes/bike3.gif");
		Image bike4=new Image("./gfx/items/bikes/bike3.gif");
		map.add(bike4);
		map.setWidgetPosition(bike4, 576,644  );
		DOM.setStyleAttribute(bike4.getElement(), "zIndex", ""+58);
		
		Image.prefetch("./gfx/items/bikes/bike4.gif");
		Image bike5=new Image("./gfx/items/bikes/bike4.gif");
		map.add(bike5);
		map.setWidgetPosition(bike5, 720,392);
		DOM.setStyleAttribute(bike5.getElement(), "zIndex", ""+37);
		
		Image.prefetch("./gfx/scenery/bush/BUSH1.gif");
		Image bush=new Image("./gfx/scenery/bush/BUSH1.gif");
		map.add(bush);
		map.setWidgetPosition(bush, 592,646);
		DOM.setStyleAttribute(bush.getElement(), "zIndex", ""+41);
		
		Image.prefetch("./gfx/scenery/bush/BUSH1.gif");
		Image bush2=new Image("./gfx/scenery/bush/BUSH1.gif");
		map.add(bush2);
		map.setWidgetPosition(bush2, 832,572);
		DOM.setStyleAttribute(bush2.getElement(), "zIndex", ""+50);
		
		Image.prefetch("./gfx/scenery/bush/BUSH2.gif");
		Image bush3=new Image("./gfx/scenery/bush/BUSH2.gif");
		map.add(bush3);
		map.setWidgetPosition(bush3, 768,596);
		DOM.setStyleAttribute(bush3.getElement(), "zIndex", ""+52);
		
		Image.prefetch("./gfx/scenery/bush/CAC1000.gif");
		Image bush4=new Image("./gfx/scenery/bush/CAC1000.gif");
		map.add(bush4);
		map.setWidgetPosition(bush4, 688,728);
		DOM.setStyleAttribute(bush4.getElement(), "zIndex", ""+67);
		
		Image.prefetch("./gfx/scenery/bush/CAC1000.gif");
		Image bush5=new Image("./gfx/scenery/bush/CAC1000.gif");
		map.add(bush5);
		map.setWidgetPosition(bush5, 976,416);
		DOM.setStyleAttribute(bush5.getElement(), "zIndex", ""+41);
		
		Image.prefetch("./gfx/scenery/bush/DROCK8.gif");
		Image bush6=new Image("./gfx/scenery/bush/DROCK8.gif");
		map.add(bush6);
		map.setWidgetPosition(bush6, 912,488);
		DOM.setStyleAttribute(bush6.getElement(), "zIndex", ""+43);
		
		Image.prefetch("./gfx/scenery/gas/GASSIGN1.gif");
		Image gas1=new Image("./gfx/scenery/gas/GASSIGN1.gif");
		map.add(gas1);
		map.setWidgetPosition(gas1, 1024,524);
		DOM.setStyleAttribute(gas1.getElement(), "zIndex", ""+59);
		
		Image.prefetch("./gfx/scenery/gas/GASPUMP5.gif");
		Image gas2=new Image("./gfx/scenery/gas/GASPUMP5.gif");
		map.add(gas2);
		map.setWidgetPosition(gas2, 1008,608);
		DOM.setStyleAttribute(gas2.getElement(), "zIndex", ""+55);
		
		Image.prefetch("./gfx/scenery/gas/PUMPNEC.gif");
		Image gas3=new Image("./gfx/scenery/gas/PUMPNEC.gif");
		map.add(gas3);
		map.setWidgetPosition(gas3, 1072,584);
		DOM.setStyleAttribute(gas3.getElement(), "zIndex", ""+52);
		
		map.setStyleName("innerAbsolutePanel");
		mapContaierPan.add(map);
		focPan = new FocusPanel();			// Place it inside a panel for
		focPan.add(mapContaierPan);					// ...mouse event capture
		focPan.addKeyboardListener(new KeyboardListenerAdapter(){
			public void onKeyPress(Widget sender, char keyCode, int modifiers) {
		        
				String keyPressed = java.lang.Character.toString(keyCode);
				if (keyPressed.equals(" ")){
					for(int i=0;i<view.getContactList().getContactCount();i++){
						if(checkTheHitterPosition(view.getContactList().getContact(i).getName()))
							view.getListener().onHit(view.getContactList().getContact(i));
                    }

					
				}
				
			}
		});
		focPan.addMouseListener(new MouseListenerAdapter()
		{	
			public void onMouseUp(Widget w,int x,int y) {
				
				int[]gridPoint=SetGridPosition(x+mouseOnMapPositionX,y+mouseOnMapPositionY);
				
				view.getContactList().getMe().gridx=gridPoint[0];
				view.getContactList().getMe().gridy=gridPoint[1];
				view.getListener().onChangeLocation(gridPoint[0], gridPoint[1]);
				
			}
			public void onMouseMove(Widget w,int x,int y){

				
				int[]gridPoint=SetGridPosition(x+mouseOnMapPositionX,y+mouseOnMapPositionY);
				map.setWidgetPosition(grid, ((gridPoint[0]*32)-(gridPoint[1]*16)),(gridPoint[1]*12));
				
//				if(x>mainGameWindowSizeWidth-40 ){
//					mapMoveRight=true;
//				}
//				if(x<mainGameWindowSizeWidth-40 || x>mainGameWindowSizeWidth-10){
//					mapMoveRight=false;
//				}
//				
//				if(x<40 ){
//					mapMoveLeft=true;
//				}
//				if(x>40 || x<10){	
//					mapMoveLeft=false;
//				}
//
//				if(y>mainGameWindowSizeHeight-40 ){
//					mapMoveDown=true;
//				}
//				if(y<mainGameWindowSizeHeight-40 || y>mainGameWindowSizeHeight-10){
//					mapMoveDown=false;
//				}
//				
//				if(y<40){
//					mapMoveUp=true;
//				}
//				if(y>40 || y<10){
//					mapMoveUp=false;
//				}
			}
		
		});
		
		grid=new Image("./MSEF000.gif");
		map.add(grid);
		map.setWidgetPosition(grid, 0, 0);
		new MapTimer().scheduleRepeating(1); // Start anim loop
		
		/*final TextBox tb=new TextBox();
		RootPanel.get("btn22").add(tb);
		
		Button hitButton = new Button("hit anim",
                new ClickListener() {
                    public void onClick(Widget widget) {
                    	
                    	view.getListener().onHit(view.contactList.getContact(tb.getText()));

                    }
                });
        RootPanel.get("btn").add(hitButton);*/
        
		/*Button dmgButton = new Button("getDMG",
                new ClickListener() {
                    public void onClick(Widget widget) {
                        allCharacters.get(tb.getText()).getDamage();
                    }
                });
        RootPanel.get("btn").add(dmgButton);*/
        
		mapContaierPan.setWidgetPosition(map, mapPositionX, mapPositionY);		
		addCharacter( view.getContactList().getMe());
		setWidget(focPan);
	}

	@SuppressWarnings("deprecation")
	public void addCharacter( final Contact contact ){
		int row=view.getContactList().getContactCount();
		if (row !=0){
			
			Character character=(Character)allCharacters.get(contact.getName());
			if(character==null){
				character=new Character(contact,map,view);
				allCharacters.put(contact.getName(), character);
			}
			
		}else{
			Character character=(Character)allCharacters.get(view.getContactList().getMe().getName());
			if(character==null){
				character=new Character(view.getContactList().getMe(),map,view);
				allCharacters.put(contact.getName(), character);
			}			
		}
	}
	
	public void removeCharacter( Contact contact ){

		allCharacters.get(contact.getName()).characterImage.removeFromParent();
		allCharacters.get(contact.getName()).charTimer.cancel();
		allCharacters.get(contact.getName()).nameLbl.removeFromParent();
		allCharacters.remove(contact.getName());
	}
	

	
	private class MapTimer extends Timer/*for map moving*/
	{	public void run()
		{	
		
//			gx.setText("gx:"+view.getContactList().getMe().gridx);
//			gy.setText("gy:"+view.getContactList().getMe().gridy);
//			x.setText("x:"+view.getContactList().getMe().charPosOnMapX);
//			y.setText("y:"+view.getContactList().getMe().charPosOnMapY);
//			mx.setText("mx:"+mapPositionX);
//			my.setText("my:"+mapPositionY);
			
			if(mapMoveRight && mapPositionX>-(startX+48-mainGameWindowSizeWidth)){
				mapPositionX-=10;
				mouseOnMapPositionX+=10;
				mapContaierPan.setWidgetPosition(map, mapPositionX, mapPositionY);
			}
			if(mapMoveLeft && mapPositionX<0) {
				mapPositionX+=10;
				mouseOnMapPositionX-=10;
				mapContaierPan.setWidgetPosition(map, mapPositionX, mapPositionY);
			}
			if(mapMoveDown && mapPositionY>-(startY+(12*lenghtOfTileOnXDirection)+12-mainGameWindowSizeHeight)){
				mapPositionY-=10;
				mouseOnMapPositionY+=10;
				mapContaierPan.setWidgetPosition(map, mapPositionX, mapPositionY);
			}
			if(mapMoveUp && mapPositionY<0){
				mapPositionY+=10;
				mouseOnMapPositionY-=10;
				mapContaierPan.setWidgetPosition(map, mapPositionX, mapPositionY);
			}
			
		}
	}
	public static int[] SetGridPosition(int mx, int my) { /*get the grid's numbers of the mouse position*/
		//referance : http://weblogs.java.net/blog/malenkov/archive/2009/02/hexagonal_tile_1.html
		int H=12;
		int R=16;
		int W=32;
		int L=4;
		int j = (int) (my / H);
		int x = mx + ( j * R);
		int i = (int) (x / W);

		my -= (double) j * H;
		if (my < L) {
			x -= (double) i * W + R;
			x *= L / R;
			if (my < Math.abs(x)) {
				j--;
				if (x < 0.0) {
					i--;
				}
			}
		}


		int [] a={i,j};
		return a;
	}
	
	public boolean checkTheHitterPosition(String nameOfHitter){
		
		int hitterX=allCharacters.get(nameOfHitter).charOngridX;
		int hitterY=allCharacters.get(nameOfHitter).charOngridX;
		
		int receiverX=allCharacters.get(view.getContactList().getMe().getName()).charOngridX;
		int receiverY=allCharacters.get(view.getContactList().getMe().getName()).charOngridX;
		
		
		if(hitterX==receiverX && hitterY==(receiverY-1)){
			return true;
		}
		else if(hitterX==(receiverX-1) && hitterY==(receiverY-1)){
			return true;
		}
		else if(hitterX==(receiverX-1) && hitterY==receiverY){
			return true;
		}
		else if(hitterX==(receiverX+1) && hitterY==receiverY){
			return true;
		}
		else if(hitterX==receiverX && hitterY==(receiverY+1)){
			return true;
		}
		else if(hitterX==(receiverX+1) && hitterY==(receiverY+1)){
			return true;
		}
		else if(hitterX==receiverX && hitterY==receiverY){
			return true;
		}
		
		return false;
	}
}
